package com.dcy.web.config;

import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.core.parser.SqlParserHelper;
import com.baomidou.mybatisplus.extension.MybatisMapWrapperFactory;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
import com.dcy.common.constant.CommonConstant;
import com.dcy.common.context.BaseContextHandler;
import com.dcy.common.properties.TenantProperties;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.StringValue;
import org.apache.ibatis.mapping.MappedStatement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;


/**
 * @Author：dcy
 * @Description: mybatis-plus 配置类
 * @Date: 2019/9/6 10:43
 */
@Configuration
@EnableConfigurationProperties(TenantProperties.class)
public class MybatisPlusConfig {

    @Autowired
    private TenantProperties tenantProperties;

    /**
     * 分页
     *
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        boolean enableTenant = tenantProperties.getEnable();
        //是否开启多租户隔离
        if (enableTenant) {
            List<ISqlParser> sqlParserList = new ArrayList<>();
            TenantSqlParser tenantSqlParser = new TenantSqlParser()
                    .setTenantHandler(new TenantHandler() {
                        @Override
                        public Expression getTenantId(boolean where) {
                            return singleTenantIdCondition();
                        }

                        private Expression singleTenantIdCondition() {
                            String tenant = BaseContextHandler.getTenantId();
                            if (tenant != null) {
                                return new StringValue(BaseContextHandler.getTenantId());
                            }
                            return new NullValue();
                        }

                        /**
                         * 获取租户列名
                         */
                        @Override
                        public String getTenantIdColumn() {
                            return CommonConstant.TENANT_ID_PARAM;
                        }

                        /**
                         * 过滤不需要根据租户隔离的表
                         * @param tableName 表名
                         */
                        @Override
                        public boolean doTableFilter(String tableName) {
                            return tenantProperties.getIgnoreTables().stream().anyMatch(
                                    (e) -> e.equalsIgnoreCase(tableName)
                            );
                        }
                    });
            sqlParserList.add(tenantSqlParser);
            paginationInterceptor.setSqlParserList(sqlParserList);
            paginationInterceptor.setSqlParserFilter(metaObject -> {
                MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
                return tenantProperties.getIgnoreSqls().stream().anyMatch(
                        (e) -> e.equalsIgnoreCase(ms.getId())
                );
            });
        }
        return paginationInterceptor;
    }


    /**
     * 下划线转骆峰
     *
     * @return
     */
    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        // 函数式编程
        return (configuration) -> {
            // 使用mybatis-plus 内置的
            configuration.setObjectWrapperFactory(new MybatisMapWrapperFactory());
        };
    }
}
